perm filename FDDERI.BCH[TIM,LSP] blob
sn#668569 filedate 1982-07-13 generic text, type C, neo UTF8
COMMENT ā VALID 00002 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 Symbolic Derivative (3)
C00007 ENDMK
Cā;
Symbolic Derivative (3)
This is the third in the series of symbolic derivative benchmarks. It uses
a faster variant of the table-driven idea used in DDERIV. In that benchmark,
the *name* of the function that took the derivative was stored under the
indicator DERIV on the property list for the function that is being
differentiated. Here we put the actual code on that property list. In the MacLisp
case, a code pointer is placed there, and a special code-pointer applier is
used. First, consider the form (DEFUN (PLUS DERIV DERIV) ...). What this
accomplishes (for our purpose) is to put the code pointer for the defined
function on the property list of PLUS under the indicator DERIV. This is
equivalent in effect to:
(DEFUN DPLUS ...)
(PUTPROP 'PLUS (GETF 'DPLUS) 'DERIV)
(REMF 'DPLUS)
where GETF gets the code pointer and REMF flushes it. In MacLisp
these could be defined as:
(DEFUN GETF (X)(GET X 'SUBR))
(DEFUN REMF (X)(REMPROP X 'SUBR))
The funny repeated reference to DERIV (as in (DEFUN (PLUS DERIV DERIV)...))
ā ā
has to do with interpreter versus compiler behavior.
SUBRCALL is like FUNCALL but takes a code pointer instead. In the
call, (SUBRCALL T DERIV (CDR A)), the `T' means that the function
returns a pointer rather than a FIXNUM (for example).
Using macros FUNCALL is (in the general case):
(DEFMACRO FUNCALL (F . X)
`(APPLY ,F (LIST . ,X)))
Here is the code:
(DECLARE (MAPEX T)) ;Causes MAPCAR to open-code
(DEFUN DER1 (A) (LIST 'QUOTIENT (DERIV A) A))
(DEFUN (PLUS DERIV DERIV) (A)
(CONS 'PLUS (MAPCAR 'DERIV A)))
(DEFUN (DIFFERENCE DERIV DERIV) (A)
(CONS 'DIFFERENCE (MAPCAR 'DERIV
A)))
(DEFUN (TIMES DERIV DERIV) (A)
(LIST 'TIMES (CONS 'TIMES A)
(CONS 'PLUS (MAPCAR 'DER1 A))))
(DEFUN (QUOTIENT DERIV DERIV) (A)
(LIST 'DIFFERENCE
(LIST 'QUOTIENT
(DERIV (CAR A))
(CADR A))
(LIST 'QUOTIENT
(CAR A)
(LIST 'TIMES
(CADR A)
(CADR A)
(DERIV (CADR A))))))
(DEFUN DERIV (A)
(COND
((ATOM A)
(COND ((EQ A 'X) 1) (T 0)))
(T (LET ((DERIV (GET (CAR A) 'DERIV)))
(COND (DERIV (SUBRCALL T DERIV (CDR A)))
(T 'ERROR))))))
(DEFUN RUN ()
(DECLARE (FIXNUM I))
(DO ((I 0 (1+ I)))
((= I 1000.))
(DERIV '(PLUS (TIMES 3 X X) (TIMES A X X) (TIMES B X) 5))
(DERIV '(PLUS (TIMES 3 X X) (TIMES A X X) (TIMES B X) 5))
(DERIV '(PLUS (TIMES 3 X X) (TIMES A X X) (TIMES B X) 5))
(DERIV '(PLUS (TIMES 3 X X) (TIMES A X X) (TIMES B X) 5))
(DERIV '(PLUS (TIMES 3 X X) (TIMES A X X) (TIMES B X) 5))))
Here is a sample run on SAIL using MacLisp:
(fasload fdderiv)
(timit)
Timing performed on Tuesday 07/06/82 at 16:27:15.
Cpu Time = 2.375
Elapsed Time = 115.166667
Wholine Time = 38.5333333
GC Time = 18.393
Load Average Before = 1.38997114
Load Average After = 1.99293315
Average Load Average = 1.69145215
Refer to this benchmark as FDDERIV.
-rpg-